package com.blog.controller;

import com.blog.common.Constant;
import com.blog.config.JwtProperties;
import com.blog.service.ChatLoggingAdvisorService;
import com.blog.utils.JwtVerifyUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.util.Date;
import java.util.Map;

/**
 * @ClassName TestController
 * @Destription 测试路由以及chatclient
 * @Author 天堂小野花
 * @Date 2025/8/17  20:20
 * @Version 1.0
 */
@RestController
@RequestMapping("/talk")
public class AiController {
    private final ChatClient chatClient;
    @Autowired
    JwtProperties jwtProperties;


    public AiController(ChatClient.Builder builder, ChatMemory  chatMemory) {
        this.chatClient = builder
                //预设角色
                .defaultSystem(
                        """
                                您是“牛犇”个人微服务博客的客户聊天支持代理。请以友好、乐于助人且愉快的方式来回复
                                您正在通过在线聊天与客户互动。
                                在提供有关下订单或者购买商品的信息之前，您必须始终从用户处获取以下信息：商品编号、购买数量。
                                在询问用户之前，请检查消息历史记录以获取此信息。
                                在下订单或者购买商品之前，请先获取商品信息并且要在用户表达确定信息之后才进行下订单
                                请讲中文。
                                用户的编号是{userId}。
                                """
                )
                //配置拦截器，启用对话记忆功能
                .defaultAdvisors(
                        new PromptChatMemoryAdvisor(chatMemory),
                        //当某些对话达不到要的效果时候，通过记录日志去分析一下，用户都问了什么
                        new ChatLoggingAdvisorService()
                )
                .defaultFunctions("createOrder","getGood")
                .build();
    }
    @GetMapping(value = "/helloChatStream",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> chatStream(String input,HttpServletRequest request){
        Map<String, Object> jwtHr = new JwtVerifyUtil().parseJwt(request.getHeader(Constant.TOKEN),jwtProperties.getSecretKey(),jwtProperties.getValidateInMs());
        Integer userId  = (Integer) jwtHr.get("id");
        //System.out.println(request.getHeader(Constant.TOKEN));
        //流式
        return  this.chatClient.prompt()
                .user(input)
                //给预设角色中的变量传值
                .system(promptSystemSpec -> promptSystemSpec.param("userId",userId))
                //对话记忆存储多大
                .advisors(advisorSpec -> advisorSpec.param(AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY,100))
                .stream()
                .content();
        // 由于这是流式在前端访问的时候如果使用EventSource是不断的访问的，需要加上一个标识，这里就可以根据标识停止。
    }

    @GetMapping(value = "/helloChatString")
    public String chatString(String input){
        //直接响应式
        return  this.chatClient.prompt()
                .user(input)
                .call()
                .content();
    }
}
